package com.jhgsys.internal.common.authentication;

import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.system.entity.Menu;
import com.jhgsys.internal.system.entity.Role;
import com.jhgsys.internal.system.entity.Tenant;
import com.jhgsys.internal.system.entity.User;
import com.jhgsys.internal.system.service.IMenuService;
import com.jhgsys.internal.system.service.IRoleService;
import com.jhgsys.internal.system.service.ITenantService;
import com.jhgsys.internal.system.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * 自定义实现 ShiroRealm，包含认证和授权两大模块
 *
 * @author MrBird
 */
@Component
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IMenuService menuService;
    @Autowired
    private ITenantService tenantService;

    /**
     * 授权模块，获取用户角色和权限
     *
     * @param principal principal
     * @return AuthorizationInfo 权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String userName = user.getUserName();

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        // 获取用户角色集
        List<Role> roleList = this.roleService.findUserRole(userName);
        Set<String> roleSet = roleList.stream().map(Role::getRoleName).collect(Collectors.toSet());
        simpleAuthorizationInfo.setRoles(roleSet);

        // 获取用户权限集
        List<Menu> permissionList = this.menuService.findUserPermissions(userName);
        Set<String> permissionSet = permissionList.stream().map(Menu::getPerms).collect(Collectors.toSet());
        simpleAuthorizationInfo.setStringPermissions(permissionSet);
        return simpleAuthorizationInfo;
    }

    /**
     * 用户认证
     *
     * @param token AuthenticationToken 身份认证 token
     * @return AuthenticationInfo 身份认证信息
     * @throws AuthenticationException 认证相关异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取用户输入的用户名和密码
        String userName = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        // 通过用户名到数据库查询用户信息
        User user = this.userService.findByName(userName);

        if (user == null) {
            throw new UnknownAccountException("用户名或密码错误！");
        }
        //wechat加密后的密码
           if(password.equals("b458bc3de6f0683ea80fdc096b03a1b1")){
               System.out.println("wechat Login!");
           }else {
               if (!StringUtils.equals(password, user.getPassword())) {
                   throw new IncorrectCredentialsException("用户名或密码错误！");
               }
           }

        if (User.STATUS_LOCK.equals(user.getStatus())) {
            throw new LockedAccountException("账号已被锁定,请联系管理员！");
        }
        String tenantId = user.getTenantId();
        Tenant tenant = tenantService.getById(tenantId);
        if(null == tenant || FebsConstant.DISABLE.equals(tenant.getStatus())){
            throw new IncorrectCredentialsException("账户归属公司状态或信息异常！");
        }
        user.setTenantName(tenant.getTenantName());
        return new SimpleAuthenticationInfo(user, password, getName());
    }

    public void clearCachedAuthorizationInfo()
    {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }
}
